<html><head><meta charset="utf-8"><title>24 条件类型，它不是三元操作符的写法吗？-慕课专栏</title>
			<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
			<meta name="renderer" content="webkit">
			<meta property="qc:admins" content="77103107776157736375">
			<meta property="wb:webmaster" content="c4f857219bfae3cb">
			<meta http-equiv="Access-Control-Allow-Origin" content="*">
			<meta http-equiv="Cache-Control" content="no-transform ">
			<meta http-equiv="Cache-Control" content="no-siteapp">
			<link rel="apple-touch-icon" sizes="76x76" href="https://www.imooc.com/static/img/common/touch-icon-ipad.png">
			<link rel="apple-touch-icon" sizes="120x120" href="https://www.imooc.com/static/img/common/touch-icon-iphone-retina.png">
			<link rel="apple-touch-icon" sizes="152x152" href="https://www.imooc.com/static/img/common/touch-icon-ipad-retina.png">
			<link href="https://moco.imooc.com/captcha/style/captcha.min.css" rel="stylesheet">
			<link rel="stylesheet" href="https://www.imooc.com/static/moco/v1.0/dist/css/moco.min.css?t=201907021539" type="text/css">
			<link rel="stylesheet" href="https://www.imooc.com/static/lib/swiper/swiper-3.4.2.min.css?t=201907021539">
			<link rel="stylesheet" href="https://static.mukewang.com/static/css/??base.css,common/common-less.css?t=2.5,column/zhuanlanChapter-less.css?t=2.5,course/inc/course_tipoff-less.css?t=2.5?v=201907051055" type="text/css">
			<link charset="utf-8" rel="stylesheet" href="https://www.imooc.com/static/lib/ueditor/themes/imooc/css/ueditor.css?v=201907021539"><link rel="stylesheet" href="https://www.imooc.com/static/lib/baiduShare/api/css/share_style0_16.css?v=6aba13f0.css"></head>
			<body><div id="main">

<div class="container clearfix" id="top" style="display: block; width: 1134px;">
    
    <div class="center_con js-center_con l" style="width: 1134px;">
        <div class="article-con">
                            <!-- 买过的阅读 -->
                <div class="map">
                    <a href="/read" target="_blank"><i class="imv2-feather-o"></i></a>
                    <a href="/read/35" target="_blank">零基础学透 TypeScript</a>
                    <a href="" target="_blank">
                        <span>
                            / 3-11 24 条件类型，它不是三元操作符的写法吗？
                        </span>
                    </a>
                </div>

            


            <div class="art-title" style="margin-top: 0px;">
                24 条件类型，它不是三元操作符的写法吗？
            </div>
            <div class="art-info">
                
                <span>
                    更新时间：2019-07-04 11:06:51
                </span>
            </div>
            <div class="art-top">
                                <img src="https://img.mukewang.com/5d0c3dc500018a9e06400359.jpg" alt="">
                                                <div class="famous-word-box">
                    <img src="https://www.imooc.com/static/img/column/bg-l.png" alt="" class="bg1 bg">
                    <img src="https://www.imooc.com/static/img/column/bg-r.png" alt="" class="bg2 bg">
                    <div class="famous-word">成功＝艰苦的劳动＋正确的方法＋少谈空话。<p class="author">——爱因斯坦</p></div>
                </div>
                            </div>
            <div class="art-content js-lookimg">
                <div><div class="cl-preview-section"><h3 id="基础使用">3.11.1 基础使用</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">条件类型是 TS2.8 引入的，从语法上看它像是三元操作符。它会以一个条件表达式进行类型关系检测，然后在后面两种类型中选择一个，先来看它怎么写：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript">T <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> X <span class="token punctuation">:</span> Y
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">这个表达式的意思是，如果 T 可以赋值给 U 类型，则是 X 类型，否则是 Y 类型。来看个实际例子：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">string</span> <span class="token operator">|</span> <span class="token keyword">number</span>
<span class="token keyword">let</span> index<span class="token punctuation">:</span> Type<span class="token operator">&lt;</span><span class="token string">'a'</span><span class="token operator">&gt;</span> <span class="token comment">// index的类型为string</span>
<span class="token keyword">let</span> index2<span class="token punctuation">:</span> Type<span class="token operator">&lt;</span><span class="token keyword">false</span><span class="token operator">&gt;</span> <span class="token comment">// index2的类型为number</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="分布式条件类型">3.11.2 分布式条件类型</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">当待检测的类型是联合类型，则该条件类型被称为“分布式条件类型”，在实例化时会自动分发成联合类型，来看例子：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> TypeName<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">any</span> <span class="token operator">?</span> T <span class="token punctuation">:</span> never<span class="token punctuation">;</span>
<span class="token keyword">type</span> Type1 <span class="token operator">=</span> TypeName<span class="token operator">&lt;</span><span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">number</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// Type1的类型是string|number</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">你可能会说，既然想指定 Type1 的类型为 string|number，为什么不直接指定，而要使用条件类型？其实这只是简单的示范，条件类型可以增加灵活性，再来看个复杂点的例子，这是官方文档的例子：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> TypeName<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">string</span>
  <span class="token operator">?</span> <span class="token keyword">string</span>
  <span class="token punctuation">:</span> T <span class="token keyword">extends</span> <span class="token class-name">number</span>
  <span class="token operator">?</span> <span class="token keyword">number</span>
  <span class="token punctuation">:</span> T <span class="token keyword">extends</span> <span class="token class-name">boolean</span>
  <span class="token operator">?</span> <span class="token keyword">boolean</span>
  <span class="token punctuation">:</span> T <span class="token keyword">extends</span> <span class="token class-name">undefined</span>
  <span class="token operator">?</span> undefined
  <span class="token punctuation">:</span> T <span class="token keyword">extends</span> <span class="token class-name">Function</span>
  <span class="token operator">?</span> <span class="token keyword">Function</span>
  <span class="token punctuation">:</span> object<span class="token punctuation">;</span>
<span class="token keyword">type</span> Type1 <span class="token operator">=</span> TypeName<span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// Type1的类型是Function</span>
<span class="token keyword">type</span> Type2 <span class="token operator">=</span> TypeName<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// Type2的类型是object</span>
<span class="token keyword">type</span> Type3 <span class="token operator">=</span> TypeName<span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token keyword">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// Type3的类型是object | Function</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">我们来看一个分布式条件类型的实际应用：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Diff<span class="token operator">&lt;</span>T<span class="token punctuation">,</span> U<span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">U</span> <span class="token operator">?</span> never <span class="token punctuation">:</span> T<span class="token punctuation">;</span>
<span class="token keyword">type</span> Test <span class="token operator">=</span> Diff<span class="token operator">&lt;</span><span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">number</span> <span class="token operator">|</span> <span class="token keyword">boolean</span><span class="token punctuation">,</span> undefined <span class="token operator">|</span> <span class="token keyword">number</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token comment">// Test的类型为string | boolean</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">这个例子定义的条件类型的作用就是，找出从 T 中出去 U 中存在的类型，得到剩下的类型。不过这个条件类型已经内置在 TS 中了，只不过它不叫 Diff，叫 Exclude，我们待会儿会讲到。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">来看一个条件类型和映射类型结合的例子：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>K <span class="token keyword">in</span> keyof T<span class="token punctuation">]</span><span class="token punctuation">:</span> T<span class="token punctuation">[</span>K<span class="token punctuation">]</span> <span class="token keyword">extends</span> <span class="token class-name">Function</span> <span class="token operator">?</span> K <span class="token punctuation">:</span> never <span class="token punctuation">}</span><span class="token punctuation">[</span>keyof T<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">interface</span> <span class="token class-name">Part</span> <span class="token punctuation">{</span>
  id<span class="token punctuation">:</span> <span class="token keyword">number</span><span class="token punctuation">;</span>
  name<span class="token punctuation">:</span> <span class="token keyword">string</span><span class="token punctuation">;</span>
  subparts<span class="token punctuation">:</span> Part<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  <span class="token function">updatePart</span><span class="token punctuation">(</span>newName<span class="token punctuation">:</span> <span class="token keyword">string</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">void</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Test <span class="token operator">=</span> Type<span class="token operator">&lt;</span>Part<span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// Test的类型为"updatePart"</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">来看一下，这个例子中，接口 Part 有四个字段，其中 updatePart 的值是函数，也就是 Function 类型。Type的定义中，涉及到映射类型、条件类型、索引访问类型和索引类型。首先[K in keyof T]用于遍历 T 的所有属性名，值使用了条件类型，T[K]是当前属性名的属性值，<code>T[K] extends Function ? K : never</code>表示如果属性值为 Function 类型，则值为属性名字面量类型，否则为 never 类型。接下来使用<code>keyof T</code>获取 T 的属性名，最后通过索引访问类型<code>[keyof T]</code>获取不为 never 的类型。</p>
</div><div class="cl-preview-section"><h3 id="条件类型的类型推断-infer">3.11.3 条件类型的类型推断-infer</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">条件类型提供一个<code>infer</code>关键字用来推断类型，我们先来看个例子。我们想定义一个条件类型，如果传入的类型是一个数组，则返回它元素的类型；如果是一个普通类型，则直接返回这个类型。来看下不使用 infer 的话，怎么写：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">any</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">?</span> T<span class="token punctuation">[</span><span class="token keyword">number</span><span class="token punctuation">]</span> <span class="token punctuation">:</span> T<span class="token punctuation">;</span>
<span class="token keyword">type</span> test <span class="token operator">=</span> Type<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// test的类型为string</span>
<span class="token keyword">type</span> test2 <span class="token operator">=</span> Type<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// test2的类型为string</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">这个例子中，如果传入 Type 的是一个数组类型，那么返回的类型为<code>T[number]</code>，也就是该数组的元素类型，如果不是数组，则直接返回这个类型。这里我们是自己通过索引访问类型<code>T[number]</code>来获取类型的，如果使用 infer 关键字则无需自己手动获取，我们来看下怎么使用 infer：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type<span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">Array</span><span class="token operator">&lt;</span>infer U<span class="token operator">&gt;</span> <span class="token operator">?</span> U <span class="token punctuation">:</span> T<span class="token punctuation">;</span>
<span class="token keyword">type</span> test <span class="token operator">=</span> Type<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// test的类型为string</span>
<span class="token keyword">type</span> test2 <span class="token operator">=</span> Type<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// test2的类型为string</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">这里 infer 能够推断出 U 的类型，并且供后面使用，你可以理解为这里定义了一个变量 U 来接收数组元素的类型。</p>
</div><div class="cl-preview-section"><h3 id="ts-预定义条件类型">3.11.4 TS 预定义条件类型</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">TS 在 2.8 版本增加了一些预定义的有条件类型，来看一下：</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">Exclude&lt;T, U&gt;，从 T 中去掉可以赋值给 U 的类型：</li>
</ul>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type <span class="token operator">=</span> Exclude<span class="token operator">&lt;</span><span class="token string">"a"</span> <span class="token operator">|</span> <span class="token string">"b"</span> <span class="token operator">|</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"a"</span> <span class="token operator">|</span> <span class="token string">"b"</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token comment">// Type =&gt; 'c'</span>
<span class="token keyword">type</span> Type2 <span class="token operator">=</span> Exclude<span class="token operator">&lt;</span><span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">number</span> <span class="token operator">|</span> <span class="token keyword">boolean</span><span class="token punctuation">,</span> <span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">number</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token comment">// Type2 =&gt; boolean</span>
</code></pre>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">Extract&lt;T, U&gt;，选取 T 中可以赋值给 U 的类型：</li>
</ul>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type <span class="token operator">=</span> Extract<span class="token operator">&lt;</span><span class="token string">"a"</span> <span class="token operator">|</span> <span class="token string">"b"</span> <span class="token operator">|</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"a"</span> <span class="token operator">|</span> <span class="token string">"c"</span> <span class="token operator">|</span> <span class="token string">"f"</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token comment">// Type =&gt; 'a' | 'c'</span>
<span class="token keyword">type</span> Type2 <span class="token operator">=</span> Extract<span class="token operator">&lt;</span><span class="token keyword">number</span> <span class="token operator">|</span> <span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">boolean</span><span class="token punctuation">,</span> <span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">boolean</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token comment">// Type2 =&gt; string | boolean</span>
</code></pre>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">NonNullable，从 T 中去掉 null 和 undefined：</li>
</ul>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type <span class="token operator">=</span> Extract<span class="token operator">&lt;</span><span class="token keyword">string</span> <span class="token operator">|</span> <span class="token keyword">number</span> <span class="token operator">|</span> undefined <span class="token operator">|</span> <span class="token keyword">null</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
<span class="token comment">// Type =&gt; string | number</span>
</code></pre>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">ReturnType，获取函数类型返回值类型：</li>
</ul>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> Type <span class="token operator">=</span> ReturnType<span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">string</span><span class="token punctuation">)</span><span class="token operator">&gt;</span>
<span class="token comment">// Type =&gt; string</span>
<span class="token keyword">type</span> Type2 <span class="token operator">=</span> ReturnType<span class="token operator">&lt;</span><span class="token punctuation">(</span>arg<span class="token punctuation">:</span> <span class="token keyword">number</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">void</span><span class="token punctuation">)</span><span class="token operator">&gt;</span>
<span class="token comment">// Type2 =&gt; void</span>
</code></pre>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">InstanceType，获取构造函数类型的实例类型：</li>
</ul>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">InstanceType直接看例子可能不好理解，所以我们先来看下它的实现：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">type</span> InstanceType<span class="token operator">&lt;</span>T <span class="token keyword">extends</span> <span class="token class-name">new</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">:</span> <span class="token keyword">any</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">any</span><span class="token operator">&gt;</span> <span class="token operator">=</span> T <span class="token keyword">extends</span> <span class="token class-name">new</span> <span class="token punctuation">(</span>
  <span class="token operator">...</span>args<span class="token punctuation">:</span> <span class="token keyword">any</span><span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> infer R
  <span class="token operator">?</span> R
  <span class="token punctuation">:</span> <span class="token keyword">any</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">InstanceType 条件类型要求泛型变量 T 类型是创建实例为 any 类型的构造函数，而它本身则通过判断 T 是否是构造函数类型来确定返回的类型。如果是构造函数，使用 infer 可以自动推断出 R 的类型，即实例类型；否则返回的是 any 类型。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">看过 InstanceType 的实现后，我们来看怎么使用：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">class</span> <span class="token class-name">A</span> <span class="token punctuation">{</span>
  <span class="token keyword">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> T1 <span class="token operator">=</span> InstanceType<span class="token operator">&lt;</span><span class="token keyword">typeof</span> A<span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// T1的类型为A</span>
<span class="token keyword">type</span> T2 <span class="token operator">=</span> InstanceType<span class="token operator">&lt;</span><span class="token keyword">any</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// T2的类型为any</span>
<span class="token keyword">type</span> T3 <span class="token operator">=</span> InstanceType<span class="token operator">&lt;</span>never<span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// T3的类型为never</span>
<span class="token keyword">type</span> T4 <span class="token operator">=</span> InstanceType<span class="token operator">&lt;</span><span class="token keyword">string</span><span class="token operator">&gt;</span><span class="token punctuation">;</span> <span class="token comment">// error</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">上面例子中，T1 的定义中，<code>typeof A</code>返回的的是类 A 的类型，也就是 A，这里不能使用 A 因为它是值不是类型，类型 A 是构造函数，所以 T1 是 A 构造函数的实例类型，也就是 A；T2 传入的类型为 any，因为 any 是任何类型的子类型，所以它满足<code>T extends new (…args: any[]) =&gt; infer R</code>，这里 infer 推断的 R 为 any；传入 never 和 any 同理。传入 string 时因为 string 不能不给构造函数类型，所以报错。</p>
</div><div class="cl-preview-section"><h3 id="本节小结">本节小结</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">本小节我们学习了条件类型的相关知识，它的语法是<code>T extends U ? X : Y</code>，我们可以形象地理解它是三元操作符的形式，<code>T extends U</code>是判断条件，如果T的类型符合U，则取类型X，否则为类型Y。我们还学习了分布式条件类型，它比较简单，是条件类型的一种特殊情况，即待检测的类型是联合类型。我们还学习了如何使用<strong>infer</strong>来更好地利用类型推断。最后我们学习了几个TypeScript中常用的内置条件类型，方便我们开发使用。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">下个小节我们将学习装饰器的基础部分，装饰器是实验性功能，ECMAScript对于装饰器的提案也是一再修改，截止到本专栏撰写时还没有定论，但是TypeScript已经实验性支持，你可以先体验下它。<br>
<img src="http://img.mukewang.com/5d03464c0001d4c316000515.jpg" alt="图片描述" data-original="http://img.mukewang.com/5d03464c0001d4c316000515.jpg" class="" style="cursor: pointer;"></p>
</div></div>
            </div>
                            <!-- 买过的阅读 -->
                <div class="art-next-prev clearfix">
                                                                        <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/35/article/360">
                                                    <div class="prev l clearfix">
                                <div class="icon l">
                                    <i class="imv2-arrow3_l"></i>
                                </div>
                                <p>
                                    23 前面跳过的unkown类型详解
                                </p>
                            </div>
                        </a>
                                                                                            <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/35/article/362">
                                                    <div class="next r clearfix">
                                <p>
                                    25 入手装饰器，给凡人添加超能力
                                </p>
                                <div class="icon r">
                                    <i class="imv2-arrow3_r"></i>
                                </div>

                            </div>
                        </a>
                                    </div>
                    </div>
        <div class="comments-con js-comments-con" id="coments_con">
        </div>



    </div>
    
    
    

</div>
 
<!-- 专栏介绍页专栏评价 -->

<!-- 专栏介绍页底部三条评价 -->

<!-- 专栏阅读页弹层目录和介绍页页面目录 -->

<!-- 专栏阅读页发布回复 -->

<!-- 专栏阅读页发布评论 -->

<!-- 专栏阅读页底部评论 -->

<!-- 专栏阅读 单个 评论 -->

<!-- 新增回复和展开三条以外回复 -->

<!-- 立即订阅的弹窗 -->












</div></body></html>